package com.shire.shire_interface.service.chat;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.shire.shire_interface.common.utils.ChatUtil;
import com.shire.shire_interface.common.utils.JsonFormat;
import com.shire.shire_interface.common.utils.JsonUtil;
import com.shire.shire_interface.common.utils.StrUtils;
import com.shire.shire_interface.constants.Constants;
import com.shire.shire_interface.constants.WxConstants;
import com.shire.shire_interface.constants.WxErrorCode;
import com.shire.shire_interface.controller.kf.WebSocketController;
import com.shire.shire_interface.dao.cs.WxChatDao;
import com.shire.shire_interface.dao.group.WxGroupMemberDao;
import com.shire.shire_interface.model.accounts.UserAccount;
import com.shire.shire_interface.model.command.WxCommand;
import com.shire.shire_interface.model.cs.WxChat;
import com.shire.shire_interface.model.cs.WxChatExample;
import com.shire.shire_interface.model.friend.WxFriend;
import com.shire.shire_interface.model.friend.WxFriendExample;
import com.shire.shire_interface.model.group.*;
import com.shire.shire_interface.model.keyword.WxKeywordReply;
import com.shire.shire_interface.model.marketing.WxGroupAwardExample;
import com.shire.shire_interface.model.marketing.WxGroupAwardWithBLOBs;
import com.shire.shire_interface.model.user.WxAccount;
import com.shire.shire_interface.service.account.WxAccountService;
import com.shire.shire_interface.service.commandcenter.BaseCommandProcessor;
import com.shire.shire_interface.service.commandcenter.WxCommandService;
import com.shire.shire_interface.service.friend.WxFriendService;
import com.shire.shire_interface.service.group.WxGroupService;
import com.shire.shire_interface.service.group.WxGroupWaitService;
import com.shire.shire_interface.service.keyword.WxKeywordReplyService;
import com.shire.shire_interface.service.marketing.WxGroupAwardService;
import com.shire.shire_interface.service.marketing.WxGroupKeywordService;
import com.shire.shire_interface.service.rule.WxRuleGroupService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class WxChatService {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());



    @Autowired
    private WxChatDao chatDao;

    @Autowired
    private WxAccountService accountService;

    @Autowired
    private WxCommandService commandService;

    @Autowired
    private BaseCommandProcessor commandProcessor;

    @Autowired
    private WxGroupWaitService groupWaitService;

    @Autowired
    private WxFriendService friendService;

    @Autowired
    private WxGroupService groupService;

    @Autowired
    private WxGroupMemberDao groupMemberDao;

    @Autowired
    private WxKeywordReplyService keywordReplyService;

    @Autowired
    private WxRuleGroupService wxRuleGroupService;

    @Autowired
    private WxGroupKeywordService groupKeywordService;

    @Autowired
    private WxGroupAwardService groupAwardService;

    public void saveChat(WxChat wxChat) {
        chatDao.insertSelective(wxChat);
    }

    public void updateChat(WxChat wxChat) {
        chatDao.updateByPrimaryKey(wxChat);
    }

    public void receiveChat(Map<String, Object> map, WxAccount account) {

        List<Map<String, Object>> chatList = (List<Map<String, Object>>) map.get("chats");
        if (chatList == null) return;
        for (Map<String, Object> chatMap : chatList) {
            this.receiveFriendChat(account, chatMap);
        }
    }

    public void respJoinGroup(WxCommand command){
        WxChatExample chatExample = new WxChatExample();
        chatExample.createCriteria().andCmdidEqualTo(command.getId());
        List<WxChat> chatList = chatDao.selectByExampleWithBLOBs(chatExample);
        for (WxChat chat : chatList) {
            chat.setSendstatus(command.getRststatus());
            chatDao.updateByPrimaryKey(chat);

            // 发送到客服
            Map<String, Object> rstMap = responseSuccess();
            rstMap.put("opType", 1);
            rstMap.put("chat", chat);
            rstMap.put("friendId", chat.getFriendid());
            rstMap.put("msgId", chat.getMsgid());
            rstMap.put("chatId", chat.getId());
            rstMap.put("sendStatus", chat.getSendstatus());
            WebSocketController.sendMessage("" + chat.getCsid(), rstMap);
        }
    }

    private void replyGroupAward(WxAccount account, WxChat wxChat, WxFriend friend){
        String groupName = wxChat.getContent().trim();
        WxGroupExample example = new WxGroupExample();
        example.createCriteria().andGroupnameEqualTo(groupName).andWxaccountEqualTo(account.getWxid());
        List<WxGroup> groupList =  groupService.selectByExample(example);
        if (groupList.size()<1){
            return; //没有找到对应的群
        }

        WxGroup group = groupList.get(0);
        WxGroupAwardExample awardExample = new WxGroupAwardExample();
        awardExample.createCriteria().andWxaccountEqualTo(account.getWxid()).andTaskgroupLike('%'+group.getGroupno()+'%');
        awardExample.setOrderByClause("createtime desc");

        List<WxGroupAwardWithBLOBs> awardList = groupAwardService.getGroupAwardHistory(awardExample);
        if (awardList.size()<0)
        {
            return; //没有对应活动
        }

        WxGroupAwardWithBLOBs award = awardList.get(0);

        Long inviteCount = groupAwardService.getInverteeCount(account.getWxid(),wxChat.getFriendwxid());
        String reply = "";
        if (inviteCount.intValue()<award.getInvitelimit().intValue()){
            //不满足条件
            reply = award.getUnqualifedmsg();
        }else {
            //满足条件
            reply = award.getReplymsg();
        }

        //不满足条件
        JSONArray msgArray = JSONArray.parseArray(reply);
        for (Object msg : msgArray) {
            JSONObject msgItem = (JSONObject) msg;
            WxConstants.MessageType type = WxConstants.MessageType.get(msgItem.getInteger("msgtype"));
            WxChat chat = new WxChat();
            chat.setWxaccount(account.getWxid());
            chat.setMsgid(String.valueOf((new Date()).getTime()));
            chat.setFriendwxid(wxChat.getFriendwxid());
            chat.setFriendNick(wxChat.getFriendNick());
            chat.setAvatar(wxChat.getAvatar());
            chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
            chat.setContent(msgItem.toJSONString());
            chat.setMsgtype(msgItem.getInteger("msgtype"));
            chat.setSendstatus(WxErrorCode.INIT_VALUE);
            chat.setReadstatus(Constants.YesNo.YES.ordinal());
            chat.setFromplat(0);
            chat.setShowstatus(Constants.YesNo.YES.getCode());
            chat.setCsid(account.getCsid());
            chat.setCreatetime(new Date());
            chat.setReadtime(new Date());
            sendChatByCmd(chat);
            sendToKf(chat, friend);
        }

    }

    private void replyForKeyword(WxAccount account, WxChat wxChat, WxGroup wxGroup) {
        if (wxChat.getMsgtype() == null)
            return;
        if (wxChat.getMsgtype() == WxConstants.MessageType.TEXT.getCode()) {
            List<WxKeywordReply> replyList = keywordReplyService.getReplayContent(wxGroup.getGroupno(), wxChat.getContent(), account);
            if (replyList == null)
                return;
            for (WxKeywordReply reply : replyList) {
                if (reply != null) {
                    if (reply.getMsgcontent().startsWith("{")) {
                        WxChat chat = new WxChat();
                        chat.setWxaccount(account.getWxid());
                        chat.setMsgid(String.valueOf((new Date()).getTime()));
                        chat.setFriendwxid(wxGroup.getGroupno());
                        chat.setFriendNick(wxGroup.getGroupname());
                        chat.setAvatar(wxGroup.getAvatar());
                        chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
                        chat.setContent(reply.getMsgcontent());
                        chat.setMsgtype(reply.getReplytype());
                        chat.setSendstatus(WxErrorCode.INIT_VALUE);
                        chat.setReadstatus(Constants.YesNo.YES.ordinal());
                        chat.setFromplat(0);
                        chat.setShowstatus(Constants.YesNo.YES.getCode());
                        chat.setCsid(account.getCsid());
                        chat.setCreatetime(new Date());
                        chat.setReadtime(new Date());
                        sendChatByCmd(chat);
                        sendToKf(chat, wxGroup);
                    } else {
                        JSONArray msgArray = JSONArray.parseArray(reply.getMsgcontent());
                        for (Object msg : msgArray) {
                            JSONObject msgItem = (JSONObject)msg;
                            WxConstants.MessageType type = WxConstants.MessageType.get(msgItem.getInteger("msgtype"));
                            if (type == WxConstants.MessageType.FORWARD_MSG){

                                JSONObject msgObj = new JSONObject();
                                msgObj.put("msgtype",1);
                                msgObj.put("content", "【自回复关键字：转发消息】"+ reply.getKeyword());
//                                msgArray.add(msgObj);
                                WxChat chat = new WxChat();
                                chat.setWxaccount(account.getWxid());
                                chat.setMsgid(String.valueOf((new Date()).getTime()));
                                chat.setFriendwxid(wxGroup.getGroupno());
                                chat.setFriendNick(wxGroup.getGroupname());
                                chat.setAvatar(wxGroup.getAvatar());
                                chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
                                chat.setContent(msgItem.toJSONString());
                                chat.setMsgtype(reply.getReplytype());
                                chat.setSendstatus(WxErrorCode.INIT_VALUE);
                                chat.setReadstatus(Constants.YesNo.YES.ordinal());
                                chat.setFromplat(0);
                                chat.setShowstatus(Constants.YesNo.YES.getCode());
                                chat.setCsid(account.getCsid());
                                chat.setCreatetime(new Date());
                                chat.setReadtime(new Date());

                                JSONObject reqObj = new JSONObject();
                                reqObj.put("toWxId", wxGroup.getGroupno());
                                reqObj.put("localId", msgItem.getString("forwardMsgId"));
                                reqObj.put("fromWxId", msgItem.getString("forwardWxid"));
                                reqObj.put("addWxid", msgItem.getBoolean("addWxid"));
                                WxCommand wxCommand = commandService.generateCmdObject(account.getCsid(),
                                        account.getId(),
                                        reqObj.toJSONString(),
                                        WxConstants.CmdTaskType.MASSMSG,
                                        -1,
                                        WxConstants.CmdType.CRK_FORWARD_MESSAGE_D,
                                        WxConstants.CmdPriority.UNKNOWN);
                                commandProcessor.addCommand(account.getCsid(),account.getId(),wxCommand);
//                                sendChatByCmd(chat);
                                saveChat(chat);
                                sendToKf(chat, wxGroup);
                            }else {
                                WxChat chat = new WxChat();
                                chat.setWxaccount(account.getWxid());
                                chat.setMsgid(String.valueOf((new Date()).getTime()));
                                chat.setFriendwxid(wxGroup.getGroupno());
                                chat.setFriendNick(wxGroup.getGroupname());
                                chat.setAvatar(wxGroup.getAvatar());
                                chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
                                chat.setContent(msgItem.toJSONString());
                                chat.setMsgtype(reply.getReplytype());
                                chat.setSendstatus(WxErrorCode.INIT_VALUE);
                                chat.setReadstatus(Constants.YesNo.YES.ordinal());
                                chat.setFromplat(0);
                                chat.setShowstatus(Constants.YesNo.YES.getCode());
                                chat.setCsid(account.getCsid());
                                chat.setCreatetime(new Date());
                                chat.setReadtime(new Date());
                                sendChatByCmd(chat);
                                sendToKf(chat, wxGroup);
                            }
                        }
                        if (reply.getReplytype() != null && reply.getReplytype() == 1){
                            JSONObject atObject = new JSONObject();
                            atObject.put("content", "@"+wxChat.getRealFromNick() + "\u2005");
                            atObject.put("wxid",wxChat.getRealFromWxId());
                            atObject.put("msgtype", 1);
                            WxChat chat = new WxChat();
                            chat.setWxaccount(account.getWxid());
                            chat.setMsgid(String.valueOf((new Date()).getTime()));
                            chat.setFriendwxid(wxGroup.getGroupno());
                            chat.setFriendNick(wxGroup.getGroupname());
                            chat.setAvatar(wxGroup.getAvatar());
                            chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
                            chat.setContent(atObject.toJSONString());
                            chat.setMsgtype(1);
                            chat.setSendstatus(WxErrorCode.INIT_VALUE);
                            chat.setReadstatus(Constants.YesNo.YES.ordinal());
                            chat.setFromplat(0);
                            chat.setShowstatus(Constants.YesNo.YES.getCode());
                            chat.setCsid(account.getCsid());
                            chat.setCreatetime(new Date());
                            chat.setReadtime(new Date());
                            sendChatByCmd(chat);
                            sendToKf(chat, wxGroup);
                        }
                    }
                    keywordReplyService.updateReplyRecodAfterSend(wxGroup.getGroupno(), account.getCsid(), reply.getId());
                }
            }

        }
    }

    private void replyFriendForKeyword(WxAccount account, WxChat wxChat, WxFriend friend) {
        if (wxChat.getMsgtype() == null)
            return;

        if (wxChat.getMsgtype() == WxConstants.MessageType.TEXT.getCode()) {
            List<WxKeywordReply> replyList = keywordReplyService.getFriendReplayContent(wxChat.getContent(), account);
            if (replyList == null)
                return;
            for (WxKeywordReply reply : replyList) {
                if (reply != null) {
                    if (reply.getMsgcontent().startsWith("{")) {
                        WxChat chat = new WxChat();
                        chat.setWxaccount(account.getWxid());
                        chat.setMsgid(String.valueOf((new Date()).getTime()));
                        chat.setFriendwxid(friend.getFriendwxid());
                        chat.setFriendNick(friend.getFriendnick());
                        chat.setAvatar(friend.getAvatar());
                        chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
                        chat.setContent(reply.getMsgcontent());
                        chat.setMsgtype(reply.getReplytype());
                        chat.setSendstatus(WxErrorCode.INIT_VALUE);
                        chat.setReadstatus(Constants.YesNo.YES.ordinal());
                        chat.setFromplat(0);
                        chat.setShowstatus(Constants.YesNo.YES.getCode());
                        chat.setCsid(account.getCsid());
                        chat.setCreatetime(new Date());
                        chat.setReadtime(new Date());
                        sendChatByCmd(chat);
                        sendToKf(chat, friend);
                        keywordReplyService.saveFriendReplyRecord(friend.getFriendwxid(), account, reply.getId());
                    }else {
                        JSONArray msgArray = JSONArray.parseArray(reply.getMsgcontent());
                        for (Object msg : msgArray) {
                            JSONObject msgItem = (JSONObject) msg;
                            WxConstants.MessageType type = WxConstants.MessageType.get(msgItem.getInteger("msgtype"));
                            if (type == WxConstants.MessageType.FORWARD_MSG){

                                JSONObject msgObj = new JSONObject();
                                msgObj.put("msgtype",1);
                                msgObj.put("content", "【自回复关键字：转发消息】"+ reply.getKeyword());
//                                msgArray.add(msgObj);
                                WxChat chat = new WxChat();
                                chat.setWxaccount(account.getWxid());
                                chat.setMsgid(String.valueOf((new Date()).getTime()));
                                chat.setFriendwxid(friend.getFriendwxid());
                                chat.setFriendNick(friend.getFriendnick());
                                chat.setAvatar(friend.getAvatar());
                                chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
                                chat.setContent(msgObj.toJSONString());
                                chat.setMsgtype(reply.getReplytype());
                                chat.setSendstatus(WxErrorCode.INIT_VALUE);
                                chat.setReadstatus(Constants.YesNo.YES.ordinal());
                                chat.setFromplat(0);
                                chat.setShowstatus(Constants.YesNo.YES.getCode());
                                chat.setCsid(account.getCsid());
                                chat.setCreatetime(new Date());
                                chat.setReadtime(new Date());

                                JSONObject reqObj = new JSONObject();
                                reqObj.put("toWxId", friend.getFriendwxid());
                                reqObj.put("localId", msgItem.getString("forwardMsgId"));
                                reqObj.put("fromWxId", msgItem.getString("forwardWxid"));
                                reqObj.put("addWxid", msgItem.getBoolean("addWxid"));
                                WxCommand wxCommand = commandService.generateCmdObject(account.getCsid(),
                                        account.getId(),
                                        reqObj.toJSONString(),
                                        WxConstants.CmdTaskType.MASSMSG,
                                        -1,
                                        WxConstants.CmdType.CRK_FORWARD_MESSAGE_D,
                                        WxConstants.CmdPriority.UNKNOWN);
                                commandProcessor.addCommand(account.getCsid(),account.getId(),wxCommand);
//                                sendChatByCmd(chat);
                                saveChat(chat);
                                sendToKf(chat, friend);
                            }else {

                                WxChat chat = new WxChat();
                                chat.setWxaccount(account.getWxid());
                                chat.setMsgid(String.valueOf((new Date()).getTime()));
                                chat.setFriendwxid(friend.getFriendwxid());
                                chat.setFriendNick(friend.getFriendnick());
                                chat.setAvatar(friend.getAvatar());
                                chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
                                chat.setContent(msgItem.toJSONString());
                                chat.setMsgtype(reply.getReplytype());
                                chat.setSendstatus(WxErrorCode.INIT_VALUE);
                                chat.setReadstatus(Constants.YesNo.YES.ordinal());
                                chat.setFromplat(0);
                                chat.setShowstatus(Constants.YesNo.YES.getCode());
                                chat.setCsid(account.getCsid());
                                chat.setCreatetime(new Date());
                                chat.setReadtime(new Date());
                                sendChatByCmd(chat);
                                sendToKf(chat, friend);
                            }
                        }
                        keywordReplyService.saveFriendReplyRecord(friend.getFriendwxid(), account, reply.getId());
                    }
                }
            }

        }
    }

    private WxGroupMember getWxGroupMember(WxAccount account, WxGroup wxGroup, String memberWxid) {
        WxGroupMemberExample memberExample = new WxGroupMemberExample();
        memberExample.createCriteria().andGroupidEqualTo(wxGroup.getId()).andWxidEqualTo(memberWxid);

        List<WxGroupMember> members = groupMemberDao.selectByExample(memberExample);
        WxGroupMember member = null;

        if (members != null && members.size() > 0)
            member = members.get(0);
        return member;
    }

    private WxGroup getWxGroup(WxAccount account, String groupWxId) {
        WxGroupExample groupExample = new WxGroupExample();
        groupExample.createCriteria().andWxaccountEqualTo(account.getWxid()).andGroupnoEqualTo(groupWxId);
        List<WxGroup> groupList = groupService.selectByExample(groupExample);

        WxGroup wxGroup = null;
        if (groupList != null && groupList.size() > 0)
            wxGroup = groupList.get(0);
        return wxGroup;
    }

    private List<Map<String, Object>> prepareGroupInfoForUpdate(Map<String, Object> chatMap) {
        Map<String, Object> fromContact = (Map<String, Object>) chatMap.get("groupInfo");
        List<Map<String, Object>> members = new ArrayList<>();
        members.add((Map<String, Object>) chatMap.get("realChatUser"));
        fromContact.put("members", members);

        List<Map<String, Object>> mapList = new ArrayList<>();
        mapList.add(fromContact);
        return mapList;
    }

    private void receiveFriendChat(WxAccount account, Map<String, Object> chatMap) {
        try {
            if (account == null) {
                // logger.warn("station[id={}]未配置wxAccount！！！！！", wxStation.getId());
                return;
            }
            String friendWxId = StrUtils.getNullStr(chatMap.get("wxId"));
//            if(friendWxId.indexOf("@chatroom")>0){
//                logger.warn("收到群消息，抛弃，不处理，wxId={}, content={}", friendWxId, JsonUtil.toJson(chatMap));
//                return;
//            }
            WxChat wxChat = new WxChat();
            wxChat.setSendstatus(WxErrorCode.SUCCESS);
            wxChat.setReadstatus(Constants.YesNo.NO.ordinal());
            wxChat.setShowstatus(Constants.YesNo.YES.getCode());
            wxChat.setCreatetime(new Date());
            wxChat.setWxaccount(account.getWxid());

            wxChat.setChatfrom(WxConstants.ChatFrom.FRIEND.getCode());
            wxChat.setMsgid(StrUtils.getNullStr(chatMap.get("msgId")));

            Integer realType = (Integer) chatMap.get("realType");
            wxChat.setMsgtype(realType);
            WxConstants.MessageType msgType = WxConstants.MessageType.get(realType);

            if (chatMap.containsKey("localId")){
                wxChat.setLocalid(chatMap.get("localId").toString());
            }

            Object contact = null;
            if (friendWxId.endsWith("@chatroom")) {
                contact = getWxGroupForChat(account, chatMap, friendWxId, wxChat);
            } else {
                contact = getWxFriendForChat(account, chatMap, friendWxId, wxChat);
            }

            if (chatMap.containsKey("realChatUser")) {
                Map<String, String> realUser = (Map<String, String>) chatMap.get("realChatUser");
                wxChat.setRealFromHeadImg(realUser.get("avatar"));
                wxChat.setRealFromNick(realUser.get("nick"));
                wxChat.setRealFromWxId(realUser.get("wxId"));
            }

            if (msgType == WxConstants.MessageType.PIC) {
                wxChat.setContent((String) chatMap.get("data"));
            } else {
                wxChat.setContent((String) chatMap.get("msg"));
            }

            if (chatMap.containsKey("msgObject")) {
                wxChat.setContent(JSONUtils.toJSONString(chatMap.get("msgObject")));
            }
            wxChat.setFriendwxid(friendWxId);
            if (msgType == WxConstants.MessageType.SHARING_GROUP_CARD) {
                int st = wxChat.getContent().indexOf("邀请你加入群聊");
                int et = wxChat.getContent().lastIndexOf("，进入可查看详情");
                if (st >= 0 && et > 0 && (st + 7) < et) {
                    String groupName = wxChat.getContent().substring(st + 7, et);
                    chatMap.put("groupName", groupName);
                }
//                    wxChat.setContent(wxChat.getContent()+"["+(String)chatMap.get("groupName")+"]");
            }
            wxChat.setCsid(account.getCsid());

            // 根据不通消息类型处理对应逻辑
            switch (msgType) {
                case SHARING_GROUP_CARD: // 收到群名片
                    receiveSharingGroupCard(chatMap, wxChat);
                    break;
                case NOTE_ADD_FRIEND_SUCCESS: // 收到添加好友成功消息
                    break;
                case NOTE_JOIN_GROUP: // 首次进入某个群消息

                    break;
                default:
                    break;
            }
            saveChat(wxChat); // 保存消息
//            if (account.getCsid() == null)
//                return;

            if (contact != null) {
                sendToKf(wxChat, contact);
            }

            if (friendWxId.endsWith("@chatroom")) {
                //群关键字回复
                if (msgType == WxConstants.MessageType.TEXT)
                    this.replyForKeyword(account, wxChat, (WxGroup) contact);

                //群规则检查
                if (((WxGroup)contact).getIsfirst() == 1)
                    checkGroupRule(account, wxChat, (WxGroup) contact);
            }else {
                //关键字拉群
                if (msgType == WxConstants.MessageType.TEXT) {
                    groupKeywordService.checkKeywordToInvite(wxChat, account, (WxFriend) contact);
                    //好友关键字回复
                    this.replyFriendForKeyword(account, wxChat, (WxFriend) contact);
                }
                if (wxChat.getContent().contains("【")){
                    this.replyGroupAward(account, wxChat, (WxFriend) contact);
                }
            }

        } catch (Exception e) {
            logger.error("接收CRK聊天信息异常[chatMap=" + chatMap + "]：", e);
        }
    }

    private void checkGroupRule(WxAccount account, WxChat wxChat, WxGroup wxGroup) {
        String warningContent = wxRuleGroupService.checkRule(account, wxChat, wxGroup);
        if (warningContent != null) {
            if (warningContent == WxRuleGroupService.DISSMISS_RET) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("groupWxId", wxGroup.getGroupno());
                jsonObject.put("userWxIds", wxChat.getRealFromWxId());

                WxCommand command = commandService.generateCmdObject(account.getCsid(),account.getId(), jsonObject.toJSONString(), WxConstants.CmdTaskType.UNKNOWN, -1, WxConstants.CmdType.CRK_REMOVE_GROUP_USERS_D,WxConstants.CmdPriority.UNKNOWN);
                commandProcessor.addCommand(wxChat.getCsid(),account.getId(), command);
            } else {
                JSONObject sendContent = new JSONObject();
                warningContent = "@"+ wxChat.getRealFromNick()+"\u2005 " + warningContent;
                sendContent.put("msgtype", 1);
                sendContent.put("content", warningContent);
                sendContent.put("wxid",wxChat.getRealFromWxId());
                WxChat chat = new WxChat();
                chat.setWxaccount(account.getWxid());
                chat.setMsgid(String.valueOf((new Date()).getTime()));
                chat.setFriendwxid(wxGroup.getGroupno());
                chat.setFriendNick(wxGroup.getGroupname());
                chat.setAvatar(wxGroup.getAvatar());
                chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());
                chat.setContent(sendContent.toJSONString());
                chat.setMsgtype(WxConstants.MessageType.TEXT.getCode());
                chat.setSendstatus(WxErrorCode.INIT_VALUE);
                chat.setReadstatus(Constants.YesNo.YES.ordinal());
                chat.setFromplat(0);
                chat.setShowstatus(Constants.YesNo.YES.getCode());
                chat.setCsid(account.getCsid());
                chat.setCreatetime(new Date());
                chat.setReadtime(new Date());
                sendChatByCmd(chat);
                sendToKf(chat, wxGroup);
            }
        }
    }

    private WxFriend getWxFriendForChat(WxAccount account, Map<String, Object> chatMap, String friendWxId, WxChat wxChat) {
        WxFriendExample friendExample = new WxFriendExample();
        friendExample.createCriteria().andWxaccountEqualTo(account.getWxid()).andFriendwxidEqualTo(friendWxId);
        List<WxFriend> wxFriendList = friendService.getAllFriends(friendExample);

        WxFriend wxFriend = null;
        if (wxFriendList != null && wxFriendList.size() > 0)
            wxFriend = wxFriendList.get(0);

        if (wxFriend == null) { // 添加好友
            Map<String, Object> fromContact = (Map<String, Object>) chatMap.get("fromContact");
            if (fromContact != null) {
                List<Map<String, Object>> reqList = new ArrayList<>();
                reqList.add(fromContact);
                friendService.syncFriendsIncrement(reqList, account);
                wxFriend = friendService.getFriendByWxId(account.getCsid(), account.getWxid(), friendWxId);
            }
        }
        wxChat.setFriendid(wxFriend != null ? wxFriend.getId() : -1);
        wxChat.setFriendremark((String) chatMap.get("nick"));
        wxChat.setFriendwxid(wxFriend.getFriendwxid());
        wxChat.setFriendNick(wxFriend.getFriendnick());
        wxChat.setFriendSignature(wxFriend.getFriendsignature());
        wxChat.setAvatar(wxFriend.getAvatar());
        return wxFriend;
    }

    private WxGroup getWxGroupForChat(WxAccount account, Map<String, Object> chatMap, String friendWxId, WxChat wxChat) {
        WxGroupExample wxGroupExample = new WxGroupExample();
        wxGroupExample.createCriteria().andWxaccountEqualTo(account.getWxid()).andGroupnoEqualTo(friendWxId);
        List<WxGroup> wxGroupList = groupService.selectByExample(wxGroupExample);

        WxGroup wxGroup = null;
        if (wxGroupList != null && wxGroupList.size() > 0)
            wxGroup = wxGroupList.get(0);

        if (wxGroup == null) { // 添加好友
            List<Map<String, Object>> fromContact = prepareGroupInfoForUpdate(chatMap);
            groupService.syncGroups("increment", fromContact, account);
            wxGroup = getWxGroup(account, friendWxId);
        }
        WxGroupMember member = null;
        if (wxGroup != null) {
            if (chatMap.containsKey("realChatUser")) {
                String memberWxid = (String) ((Map) chatMap.get("realChatUser")).get("wxId");
                if (memberWxid != null) {
                    member = getWxGroupMember(account, wxGroup, memberWxid);

                    if (member == null) {
                        List<Map<String, Object>> fromContact = prepareGroupInfoForUpdate(chatMap);
                        groupService.syncGroups("increment", fromContact, account);
                    }
                }
            }
        }


        wxChat.setFriendid(wxGroup != null ? wxGroup.getId() : -1);
        wxChat.setFriendremark(wxGroup.getFriendremark());
        wxChat.setFriendwxid(wxGroup.getGroupno());
        wxChat.setFriendNick(chatMap.get("nick").toString());
        wxChat.setAvatar(wxGroup.getAvatar());
        return wxGroup;
    }

    public void sendToKf(WxChat wxChat, Object wxFriend) {
        List<UserAccount> list = accountService.getSystemUserByWxid(wxChat.getWxaccount());
        for(UserAccount account : list) {
//        wxFriend.setLatestChat(wxChat); //TODO
            Map<String, Object> sendMap = new HashMap<>();
//        if(accountService.isOneOfCs(wxFriend.getFriendwxid()) || accountService.isOneOfCs(wxFriend.getFriendalias())){
//            wxFriend.setOneOfUs(true);//TODO
//        }
            sendMap.put("opType", 2); // 聊天消息
            sendMap.put("friend", wxFriend);
            sendMap.put("chat", wxChat);
            WebSocketController.sendMessage("" + account.getUserId(), JsonFormat.toJson(sendMap));
        }
    }

    /**
     * 收到群名片消息，将信息添加到群等待表WxGroupWait
     *
     * @param map
     * @param wxChat
     */
    public void receiveSharingGroupCard(Map<String, Object> map, WxChat wxChat) {
        WxGroupWait wxGroupWait = new WxGroupWait();
        wxGroupWait.setWxaccount(wxChat.getWxaccount());
        wxGroupWait.setScore(100);
        wxGroupWait.setFriendid(wxChat.getFriendid());
        wxGroupWait.setFriendwxid(wxChat.getFriendwxid());
        wxGroupWait.setFriendremark(wxChat.getFriendremark());
        wxGroupWait.setMsgid(wxChat.getMsgid());
        wxGroupWait.setGroupname((String) map.get("groupName"));
        wxGroupWait.setCsid(wxChat.getCsid());
        wxGroupWait.setRststatus(WxErrorCode.INIT_VALUE);
        wxGroupWait.setCmdstatus(WxConstants.CmdStatus.NEW.getCode());
        wxGroupWait.setCreatetime(new Date());
        wxGroupWait.setUpdatetime(new Date());
        // 检测敏感词
//        try{
//            String word = wxSensitiveService.searchGroupWaitSensitive(wxGroupWait.getGroupName());
//            if(StrUtils.isNotBlank(word)){
//                wxGroupWait.setRstStatus(WxErrorCode.GROUP_WAIT_SENSITIVE);
//                wxGroupWait.setCmdStatus(WxConstants.CmdStatus.ABANDON.getCode());
//                wxChat.setContent("[敏感词<"+word+">]"+wxChat.getContent());
//            }
//        }
//        catch (Exception e){
//        }
        groupWaitService.insertGroupWait(wxGroupWait);
    }

    public Map<String, Object> sendChatByCmd(WxChat wxChat) {
        WxAccount wxAccount = accountService.getWxAccountByAccountName(wxChat.getCsid(), wxChat.getWxaccount());
        if (wxAccount == null) {
            logger.error("wxAccount不存在！");
            return responseFailure("wxAccount不存在！");
        }
        // 暂只支持文字
        logger.info("wxAccount存在！");
        JSONObject reqJson = new JSONObject();

        WxConstants.CmdType cmdType = ChatUtil.getMsgRepContent(wxChat.getContent(), reqJson, wxChat.getFriendwxid(), wxChat.getFriendAlias(), wxChat.getFriendNick());

        try {
            if (wxChat.getId() == null || wxChat.getId() <= 0) {
                chatDao.insert(wxChat);
            }
            logger.info("wxAccount存在！接入命令");
            WxCommand wxCommand = commandService.generateCmdObject(wxChat.getCsid(),
                    wxAccount.getId(),
                    reqJson.toJSONString(),
                    WxConstants.CmdTaskType.UNKNOWN,
                    0,
                    cmdType,
                    WxConstants.CmdPriority.UNKNOWN);

            wxChat.setCmdid(wxCommand.getId().longValue());
            wxChat.setSendstatus(wxCommand.getRststatus());
            chatDao.updateByPrimaryKey(wxChat);
            commandProcessor.addCommand(wxAccount.getCsid(), wxAccount.getId(), wxCommand);
            return responseSuccess();
        } catch (Exception e) {
            logger.error("发送至CRK的消息异常[acountId=" + wxAccount.getId() + ", wxChat=" + wxChat.getContent() + "]：", e);
            return responseFailure(-1, "发送至CRK异常");
        }
    }


    public void respSendChat(WxCommand wxCommand, Map<String, Object> respContent) {
        WxChatExample chatExample = new WxChatExample();
        chatExample.createCriteria().andCmdidEqualTo(wxCommand.getId().longValue());
        List<WxChat> wxChatList = chatDao.selectByExampleWithBLOBs(chatExample);

        for (WxChat wxChat : wxChatList) {
            if (wxChat != null) {
                wxChat.setSendstatus(wxCommand.getRststatus());
                wxChat.setSendtime(new Date());
                if (respContent != null) {
                    wxChat.setLocalid(String.valueOf(respContent.get("localId")));
                }
                chatDao.updateByPrimaryKey(wxChat);
                // 发送到客服
                Map<String, Object> rstMap = responseSuccess();
                rstMap.put("opType", 1);
                rstMap.put("chat", wxChat);
                rstMap.put("friendId", wxChat.getFriendid());
                rstMap.put("msgId", wxChat.getMsgid());
                rstMap.put("chatId", wxChat.getId());
                rstMap.put("sendStatus", wxChat.getSendstatus());
                WebSocketController.sendMessage("" + wxChat.getCsid(), rstMap);
            }
        }
    }

    public List<WxChat> getFriendChatList(Integer csId, String accountWxId, String friendWxId, int pageStart, int pageSize) {
        WxChatExample example = new WxChatExample();
        example.createCriteria().andWxaccountEqualTo(accountWxId).andFriendwxidEqualTo(friendWxId);
        example.setLimitStart(pageStart);
        example.setLimitSize(pageSize);
        example.setOrderByClause("id desc");
        List<WxChat> chats = chatDao.selectByExampleWithBLOBs(example);

        return chats;
    }

    public void setChatReadStatus(Integer chatId, Integer readStatus) {
        WxChat chat = new WxChat();
        chat.setReadstatus(readStatus);
        chat.setReadtime(new Date());
        WxChatExample example = new WxChatExample();
        example.createCriteria().andIdEqualTo(chatId.longValue());

        chatDao.updateByExampleSelective(chat, example);
    }

    public void setChatShowStatusNo(Integer csId, String accountWxId, String friendWxId) {
        WxChatExample example = new WxChatExample();
        example.createCriteria().andFriendwxidEqualTo(friendWxId).andWxaccountEqualTo(accountWxId);
        example.setLimitStart(0);
        example.setLimitSize(1);//取最近一条
        example.setOrderByClause("id desc");
        List<WxChat> chats = chatDao.selectByExampleWithBLOBs(example);

        if (chats != null && chats.size() > 0) {
            WxChat lastChat = chats.get(0);
            lastChat.setShowstatus(Constants.YesNo.NO.getCode());
            chatDao.updateByPrimaryKey(lastChat);
        }
    }

    public boolean cancelChat(Integer chatId) {
        WxChat wxChat = chatDao.selectByPrimaryKey(chatId.longValue());
        if (wxChat == null) {
            return true;
        }

        return false;
    }

    public WxChat genNoticeChat(Long cmdId, String msgId, Object wxFriend, String content, Integer csId) {
        WxChat chat = new WxChat();
        chat.setCmdid(cmdId);
        chat.setMsgid(msgId);
        if (wxFriend instanceof WxFriend) {
            WxFriend friend = (WxFriend) wxFriend;
            chat.setWxaccount(friend.getWxaccount());
            chat.setFriendid(friend.getId());
            chat.setFriendwxid(friend.getFriendwxid());
            chat.setFriendremark(friend.getFriendremark());
        }else {
            WxGroup group = (WxGroup) wxFriend;
            chat.setWxaccount(group.getWxaccount());
            chat.setFriendid(group.getId());
            chat.setFriendwxid(group.getFriendwxid());
            chat.setFriendremark(group.getFriendremark());
        }

        chat.setChatfrom(WxConstants.ChatFrom.SELF.getCode());

        JSONObject contentJSON = new JSONObject();

        try{
            contentJSON = JSONObject.parseObject(content);
        }catch (Exception e) {
            contentJSON.put("msgtype", WxConstants.MessageType.TEXT.getCode());
            contentJSON.put("content", content);
        }

        chat.setContent(contentJSON.toJSONString());

        chat.setMsgtype(WxConstants.MessageType.TEXT.getCode());
        chat.setSendstatus(WxErrorCode.SUCCESS);
        chat.setReadstatus(Constants.YesNo.YES.getCode());
        chat.setCsid(csId);
        chat.setCreatetime(new Date());
        saveChat(chat);
        Map<String, Object> rstMap = responseSuccess();
        rstMap.put("opType", 1);
        rstMap.put("chat", chat);
//        rstMap.put("friendId", wxFriend.getId());
        rstMap.put("msgId", msgId);
        WebSocketController.sendMessage("" + csId, rstMap);
        return chat;
    }


    public boolean scanImage(Integer csId, Integer chatId, String message) {
        WxChat wxChat = chatDao.selectByPrimaryKey(chatId.longValue());
        if (wxChat == null) {
            logger.warn("聊天记录不存在， chatId={}", chatId);
            return false;
        }
        WxConstants.MessageType messageType = WxConstants.MessageType.get(wxChat.getMsgtype());
        if (messageType == WxConstants.MessageType.PIC) {
            WxAccount wxAccount = accountService.getWxAccountByAccountName(csId, wxChat.getWxaccount());
            if (wxAccount == null) {
                logger.warn("微信账号wxAccount={}不存在", wxChat.getWxaccount());
                return false;
            }
            Map<String, Object> reqMap = new HashMap<>();
            reqMap.put("wxId", wxChat.getFriendwxid());
            reqMap.put("msgId", wxChat.getMsgid());
            reqMap.put("message", message);

            WxCommand wxCommand = commandService.generateCmdObject(csId,
                    wxAccount.getId(),
                    JsonUtil.toJson(reqMap),
                    WxConstants.CmdTaskType.UNKNOWN,
                    0,
                    WxConstants.CmdType.CRK_SCAN_IMAGE,
                    WxConstants.CmdPriority.UNKNOWN);

            commandProcessor.addCommand(wxAccount.getCsid(), wxAccount.getId(), wxCommand);
//                    wxCommandService.addWxCommand(csId, wxAccount.getStationId(), WxConstants.CmdType.CRK_SCAN_IMAGE, ""+chatId,
//                    JsonFormat.toJson(reqMap), new Date());
            if (wxCommand == null) {
                logger.warn("创建识别指令错误！！chatId={}", chatId);
                return false;
            }
            wxChat.setCmdid(wxCommand.getId().longValue());
            wxChat.setSendstatus(wxCommand.getRststatus());
            wxChat.setSendtime(new Date());
            updateChat(wxChat);
            return true;
        }
        return false;
    }

    public boolean addFriendByCard(Integer csId, Integer chatId, String message) {
        WxChat wxChat = chatDao.selectByPrimaryKey(chatId.longValue());
        if (wxChat == null) {
            logger.warn("聊天记录不存在， chatId={}", chatId);
            return false;
        }
        WxConstants.MessageType messageType = WxConstants.MessageType.get(wxChat.getMsgtype());
        if (messageType == WxConstants.MessageType.FRIEND_CARD) {
            WxAccount wxAccount = accountService.getWxAccountByAccountName(csId, wxChat.getWxaccount());
            if (wxAccount == null) {
                logger.warn("微信账号wxAccount={}不存在", wxChat.getCsid());
                return false;
            }
            Map<String, Object> reqMap = new HashMap<>();
            reqMap.put("wxId", wxChat.getFriendwxid());
            reqMap.put("userName", wxChat.getFriendwxid());
            reqMap.put("message", message);
            reqMap.put("msgId", wxChat.getMsgid());

            WxCommand wxCommand = commandService.generateCmdObject(csId,
                    wxAccount.getId(),
                    JsonUtil.toJson(reqMap),
                    WxConstants.CmdTaskType.UNKNOWN,
                    0,
                    WxConstants.CmdType.CRK_ACCEPT_CARD,
                    WxConstants.CmdPriority.UNKNOWN);
            commandProcessor.addCommand(csId, wxAccount.getId(), wxCommand);

            if (wxCommand == null) {
                logger.warn("创建识别指令错误！！chatId={}", chatId);
                return false;
            }
            wxChat.setCmdid(wxCommand.getId());
            wxChat.setSendstatus(wxCommand.getRststatus());
            wxChat.setSendtime(new Date());
            updateChat(wxChat);
            return true;
        }
        return false;
    }

    public Map<String, Object> responseSuccess() {
        return responseSuccess("操作成功");
    }

    public Map<String, Object> responseSuccess(String msg) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", true);
        result.put("status", 0);
        result.put("msg", msg);
        return result;
    }

    public Map<String, Object> responseFailure() {
        return responseFailure("操作失败");
    }

    public Map<String, Object> responseFailure(String msg) {
        return responseFailure(-1, msg);
    }

    public Map<String, Object> responseFailure(Integer status, String msg) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", false);
        result.put("status", status);
        result.put("msg", msg);
        return result;
    }
    public List<WxChat> getMaxChatId(WxChatExample example){
        return chatDao.selectMaxIdForAccount(example);
    }

    public List<WxChat> chatFriend(WxChatExample example) {

        return chatDao.selectByExample(example);

    }

    public WxChat selectByPrimaryKey(Integer chatId) {

        return chatDao.selectByPrimaryKey(chatId.longValue());
    }


    public Long countByExample(WxChatExample wxChartExample) {

        return chatDao.countByExample(wxChartExample);
    }

    public int updateByExample(WxChat wxChat, WxChatExample wxChatExample) {

        return chatDao.updateByExampleSelective(wxChat, wxChatExample);
    }

    public List<WxChat> selectByExample(WxChatExample wxChatExample) {
        return chatDao.selectByExample(wxChatExample);
    }

    public int updateByExampleSelective(WxChat wxChat, WxChatExample wxChatExample) {
        return chatDao.updateByExampleSelective(wxChat,wxChatExample);
    }
}
